package top.cyuw.simplerpc.registry.zookeeper;

import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import top.cyuw.simplerpc.URL;
import top.cyuw.simplerpc.config.RpcServiceConfig;
import top.cyuw.simplerpc.constant.RpcConstants;
import top.cyuw.simplerpc.registry.memory.MemoryServiceRegistry;

import java.net.InetSocketAddress;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author chen
 * @date 2023/3/16 21:04
 */
@Slf4j
public class ZookeeperServiceRegistry extends MemoryServiceRegistry {

    private final Set<String> registeredNodeNames = ConcurrentHashMap.newKeySet();

    @Override
    public void registerService(RpcServiceConfig serviceConfig, InetSocketAddress address) {
        super.registerService(serviceConfig, address);

        String nodeName = UUID.randomUUID().toString();
        String path = RpcConstants.URL_SEPARATOR + nodeName;
        Map<String, String> parameters = new HashMap<>();
        parameters.put("version", serviceConfig.getVersion());
        parameters.put("group", serviceConfig.getGroup());
        URL url = new URL(RpcConstants.URL_PROTOCOL, address.getHostName(), address.getPort(), serviceConfig.getFullServiceName(), parameters);

        try {
            CuratorFramework zkClient = ZookeeperClientUtils.createZkClient();
            ZookeeperClientUtils.createEphemeralNode(zkClient, ZookeeperClientUtils.ROOT_PATH + path, url.toString());
            registeredNodeNames.add(nodeName);
        } catch (Exception e) {
            log.error("create ephemeral node for path " + ZookeeperClientUtils.ROOT_PATH + path + " failed: " + e.getMessage(), e);
        }
    }

    @Override
    public void clear() {
        super.clear();
        try {
            CuratorFramework zkClient = ZookeeperClientUtils.createZkClient();
            for (String nodeName : registeredNodeNames) {
                ZookeeperClientUtils.deleteNode(zkClient, ZookeeperClientUtils.ROOT_PATH + RpcConstants.URL_SEPARATOR + nodeName);
            }
        } catch (Exception e) {
            log.error("clear registered zookeeper nodes failed: " + e.getMessage(), e);
        }
        registeredNodeNames.clear();
    }
}
